home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the 3D Game Programming Gurus / gurus.iso / DirectX / dx9sdkcp.exe / SDK (C++) / Bin / DXUtils / Visual Studio 6.0 Wizards / Source Code / Template / d3denumeration.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-12  |  26.1 KB  |  736 lines

  1. //-----------------------------------------------------------------------------
  2. // File: D3DEnumeration.cpp
  3. //
  4. // Desc: Enumerates D3D adapters, devices, modes, etc.
  5. //-----------------------------------------------------------------------------
  6. #define STRICT
  7. $$IF(DLG)
  8. #include "stdafx.h"
  9. $$ENDIF
  10. #include <windows.h>
  11. #include <D3D9.h>
  12. #include "DXUtil.h"
  13. #include "D3DEnumeration.h"
  14.  
  15.  
  16. //-----------------------------------------------------------------------------
  17. // Name: ColorChannelBits
  18. // Desc: Returns the number of color channel bits in the specified D3DFORMAT
  19. //-----------------------------------------------------------------------------
  20. static UINT ColorChannelBits( D3DFORMAT fmt )
  21. {
  22.     switch( fmt )
  23.     {
  24.         case D3DFMT_R8G8B8:
  25.             return 8;
  26.         case D3DFMT_A8R8G8B8:
  27.             return 8;
  28.         case D3DFMT_X8R8G8B8:
  29.             return 8;
  30.         case D3DFMT_R5G6B5:
  31.             return 5;
  32.         case D3DFMT_X1R5G5B5:
  33.             return 5;
  34.         case D3DFMT_A1R5G5B5:
  35.             return 5;
  36.         case D3DFMT_A4R4G4B4:
  37.             return 4;
  38.         case D3DFMT_R3G3B2:
  39.             return 2;
  40.         case D3DFMT_A8R3G3B2:
  41.             return 2;
  42.         case D3DFMT_X4R4G4B4:
  43.             return 4;
  44.         case D3DFMT_A2B10G10R10:
  45.             return 10;
  46.         case D3DFMT_A2R10G10B10:
  47.             return 10;
  48.         default:
  49.             return 0;
  50.     }
  51. }
  52.  
  53.  
  54.  
  55.  
  56. //-----------------------------------------------------------------------------
  57. // Name: AlphaChannelBits
  58. // Desc: Returns the number of alpha channel bits in the specified D3DFORMAT
  59. //-----------------------------------------------------------------------------
  60. static UINT AlphaChannelBits( D3DFORMAT fmt )
  61. {
  62.     switch( fmt )
  63.     {
  64.         case D3DFMT_R8G8B8:
  65.             return 0;
  66.         case D3DFMT_A8R8G8B8:
  67.             return 8;
  68.         case D3DFMT_X8R8G8B8:
  69.             return 0;
  70.         case D3DFMT_R5G6B5:
  71.             return 0;
  72.         case D3DFMT_X1R5G5B5:
  73.             return 0;
  74.         case D3DFMT_A1R5G5B5:
  75.             return 1;
  76.         case D3DFMT_A4R4G4B4:
  77.             return 4;
  78.         case D3DFMT_R3G3B2:
  79.             return 0;
  80.         case D3DFMT_A8R3G3B2:
  81.             return 8;
  82.         case D3DFMT_X4R4G4B4:
  83.             return 0;
  84.         case D3DFMT_A2B10G10R10:
  85.             return 2;
  86.         case D3DFMT_A2R10G10B10:
  87.             return 2;
  88.         default:
  89.             return 0;
  90.     }
  91. }
  92.  
  93.  
  94.  
  95.  
  96. //-----------------------------------------------------------------------------
  97. // Name: DepthBits
  98. // Desc: Returns the number of depth bits in the specified D3DFORMAT
  99. //-----------------------------------------------------------------------------
  100. static UINT DepthBits( D3DFORMAT fmt )
  101. {
  102.     switch( fmt )
  103.     {
  104.         case D3DFMT_D16:
  105.             return 16;
  106.         case D3DFMT_D15S1:
  107.             return 15;
  108.         case D3DFMT_D24X8:
  109.             return 24;
  110.         case D3DFMT_D24S8:
  111.             return 24;
  112.         case D3DFMT_D24X4S4:
  113.             return 24;
  114.         case D3DFMT_D32:
  115.             return 32;
  116.         default:
  117.             return 0;
  118.     }
  119. }
  120.  
  121.  
  122.  
  123.  
  124. //-----------------------------------------------------------------------------
  125. // Name: StencilBits
  126. // Desc: Returns the number of stencil bits in the specified D3DFORMAT
  127. //-----------------------------------------------------------------------------
  128. static UINT StencilBits( D3DFORMAT fmt )
  129. {
  130.     switch( fmt )
  131.     {
  132.         case D3DFMT_D16:
  133.             return 0;
  134.         case D3DFMT_D15S1:
  135.             return 1;
  136.         case D3DFMT_D24X8:
  137.             return 0;
  138.         case D3DFMT_D24S8:
  139.             return 8;
  140.         case D3DFMT_D24X4S4:
  141.             return 4;
  142.         case D3DFMT_D32:
  143.             return 0;
  144.         default:
  145.             return 0;
  146.     }
  147. }
  148.  
  149.  
  150.  
  151.  
  152. //-----------------------------------------------------------------------------
  153. // Name: D3DAdapterInfo destructor
  154. // Desc: 
  155. //-----------------------------------------------------------------------------
  156. D3DAdapterInfo::~D3DAdapterInfo( void )
  157. {
  158.     if( pDisplayModeList != NULL )
  159.         delete pDisplayModeList;
  160.     if( pDeviceInfoList != NULL )
  161.     {
  162.         for( UINT idi = 0; idi < pDeviceInfoList->Count(); idi++ )
  163.             delete (D3DDeviceInfo*)pDeviceInfoList->GetPtr(idi);
  164.         delete pDeviceInfoList;
  165.     }
  166. }
  167.  
  168.  
  169.  
  170.  
  171. //-----------------------------------------------------------------------------
  172. // Name: D3DDeviceInfo destructor
  173. // Desc: 
  174. //-----------------------------------------------------------------------------
  175. D3DDeviceInfo::~D3DDeviceInfo( void )
  176. {
  177.     if( pDeviceComboList != NULL )
  178.     {
  179.         for( UINT idc = 0; idc < pDeviceComboList->Count(); idc++ )
  180.             delete (D3DDeviceCombo*)pDeviceComboList->GetPtr(idc);
  181.         delete pDeviceComboList;
  182.     }
  183. }
  184.  
  185.  
  186.  
  187.  
  188. //-----------------------------------------------------------------------------
  189. // Name: D3DDeviceCombo destructor
  190. // Desc: 
  191. //-----------------------------------------------------------------------------
  192. D3DDeviceCombo::~D3DDeviceCombo( void )
  193. {
  194.     if( pDepthStencilFormatList != NULL )
  195.         delete pDepthStencilFormatList;
  196.     if( pMultiSampleTypeList != NULL )
  197.         delete pMultiSampleTypeList;
  198.     if( pMultiSampleQualityList != NULL )
  199.         delete pMultiSampleQualityList;
  200.     if( pDSMSConflictList != NULL )
  201.         delete pDSMSConflictList;
  202.     if( pVertexProcessingTypeList != NULL )
  203.         delete pVertexProcessingTypeList;
  204.     if( pPresentIntervalList != NULL )
  205.         delete pPresentIntervalList;
  206. }
  207.  
  208.  
  209.  
  210. //-----------------------------------------------------------------------------
  211. // Name: CD3DEnumeration constructor
  212. // Desc: 
  213. //-----------------------------------------------------------------------------
  214. CD3DEnumeration::CD3DEnumeration()
  215. {
  216.     m_pAdapterInfoList = NULL;
  217.     m_pAllowedAdapterFormatList = NULL;
  218.     AppMinFullscreenWidth = 640;
  219.     AppMinFullscreenHeight = 480;
  220.     AppMinColorChannelBits = 5;
  221.     AppMinAlphaChannelBits = 0;
  222.     AppMinDepthBits = 15;
  223.     AppMinStencilBits = 0;
  224.     AppUsesDepthBuffer = false;
  225.     AppUsesMixedVP = false;
  226.     AppRequiresWindowed = false;
  227.     AppRequiresFullscreen = false;
  228. }
  229.  
  230.  
  231.  
  232.  
  233. //-----------------------------------------------------------------------------
  234. // Name: CD3DEnumeration destructor
  235. // Desc: 
  236. //-----------------------------------------------------------------------------
  237. CD3DEnumeration::~CD3DEnumeration()
  238. {
  239.     if( m_pAdapterInfoList != NULL )
  240.     {
  241.         for( UINT iai = 0; iai < m_pAdapterInfoList->Count(); iai++ )
  242.             delete (D3DAdapterInfo*)m_pAdapterInfoList->GetPtr(iai);
  243.         delete m_pAdapterInfoList;
  244.     }
  245.     SAFE_DELETE( m_pAllowedAdapterFormatList );
  246. }
  247.  
  248.  
  249.  
  250.  
  251. //-----------------------------------------------------------------------------
  252. // Name: SortModesCallback
  253. // Desc: Used to sort D3DDISPLAYMODEs
  254. //-----------------------------------------------------------------------------
  255. static int __cdecl SortModesCallback( const void* arg1, const void* arg2 )
  256. {
  257.     D3DDISPLAYMODE* pdm1 = (D3DDISPLAYMODE*)arg1;
  258.     D3DDISPLAYMODE* pdm2 = (D3DDISPLAYMODE*)arg2;
  259.  
  260.     if (pdm1->Width > pdm2->Width)
  261.         return 1;
  262.     if (pdm1->Width < pdm2->Width)
  263.         return -1;
  264.     if (pdm1->Height > pdm2->Height)
  265.         return 1;
  266.     if (pdm1->Height < pdm2->Height)
  267.         return -1;
  268.     if (pdm1->Format > pdm2->Format)
  269.         return 1;
  270.     if (pdm1->Format < pdm2->Format)
  271.         return -1;
  272.     if (pdm1->RefreshRate > pdm2->RefreshRate)
  273.         return 1;
  274.     if (pdm1->RefreshRate < pdm2->RefreshRate)
  275.         return -1;
  276.     return 0;
  277. }
  278.  
  279.  
  280.  
  281.  
  282. //-----------------------------------------------------------------------------
  283. // Name: Enumerate
  284. // Desc: Enumerates available D3D adapters, devices, modes, etc.
  285. //-----------------------------------------------------------------------------
  286. HRESULT CD3DEnumeration::Enumerate()
  287. {
  288.     HRESULT hr;
  289.     CArrayList adapterFormatList( AL_VALUE, sizeof(D3DFORMAT) );
  290.  
  291.     if( m_pD3D == NULL )
  292.         return E_FAIL;
  293.  
  294.     m_pAdapterInfoList = new CArrayList( AL_REFERENCE );
  295.     if( m_pAdapterInfoList == NULL )
  296.         return E_OUTOFMEMORY;
  297.  
  298.     m_pAllowedAdapterFormatList = new CArrayList( AL_VALUE, sizeof(D3DFORMAT) );
  299.     if( m_pAllowedAdapterFormatList == NULL )
  300.         return E_OUTOFMEMORY;
  301.     D3DFORMAT fmt;
  302.     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_X8R8G8B8 ) ) ) )
  303.         return hr;
  304.     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_X1R5G5B5 ) ) ) )
  305.         return hr;
  306.     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_R5G6B5 ) ) ) )
  307.         return hr;
  308.     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_A2R10G10B10 ) ) ) )
  309.         return hr;
  310.  
  311.     D3DAdapterInfo* pAdapterInfo = NULL;
  312.     UINT numAdapters = m_pD3D->GetAdapterCount();
  313.  
  314.     for (UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++)
  315.     {
  316.         pAdapterInfo = new D3DAdapterInfo;
  317.         if( pAdapterInfo == NULL )
  318.             return E_OUTOFMEMORY;
  319.         pAdapterInfo->pDisplayModeList = new CArrayList( AL_VALUE, sizeof(D3DDISPLAYMODE)); 
  320.         pAdapterInfo->pDeviceInfoList = new CArrayList( AL_REFERENCE );
  321.         if( pAdapterInfo->pDisplayModeList == NULL ||
  322.             pAdapterInfo->pDeviceInfoList == NULL )
  323.         {
  324.             delete pAdapterInfo;
  325.             return E_OUTOFMEMORY;
  326.         }
  327.         pAdapterInfo->AdapterOrdinal = adapterOrdinal;
  328.         m_pD3D->GetAdapterIdentifier(adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier);
  329.  
  330.         // Get list of all display modes on this adapter.  
  331.         // Also build a temporary list of all display adapter formats.
  332.         adapterFormatList.Clear();
  333.         for( UINT iaaf = 0; iaaf < m_pAllowedAdapterFormatList->Count(); iaaf++ )
  334.         {
  335.             D3DFORMAT allowedAdapterFormat = *(D3DFORMAT*)m_pAllowedAdapterFormatList->GetPtr( iaaf );
  336.             UINT numAdapterModes = m_pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat );
  337.             for (UINT mode = 0; mode < numAdapterModes; mode++)
  338.             {
  339.                 D3DDISPLAYMODE displayMode;
  340.                 m_pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode );
  341.                 if( displayMode.Width < AppMinFullscreenWidth ||
  342.                     displayMode.Height < AppMinFullscreenHeight ||
  343.                     ColorChannelBits(displayMode.Format) < AppMinColorChannelBits )
  344.                 {
  345.                     continue;
  346.                 }
  347.                 pAdapterInfo->pDisplayModeList->Add(&displayMode);
  348.                 if( !adapterFormatList.Contains( &displayMode.Format ) )
  349.                     adapterFormatList.Add( &displayMode.Format );
  350.             }
  351.         }
  352.  
  353.         // Sort displaymode list
  354.         qsort( pAdapterInfo->pDisplayModeList->GetPtr(0), 
  355.             pAdapterInfo->pDisplayModeList->Count(), sizeof( D3DDISPLAYMODE ),
  356.             SortModesCallback );
  357.  
  358.         // Get info for each device on this adapter
  359.         if( FAILED( hr = EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) )
  360.         {
  361.             delete pAdapterInfo;
  362.             return hr;
  363.         }
  364.  
  365.         // If at least one device on this adapter is available and compatible
  366.         // with the app, add the adapterInfo to the list
  367.         if (pAdapterInfo->pDeviceInfoList->Count() == 0)
  368.             delete pAdapterInfo;
  369.         else
  370.             m_pAdapterInfoList->Add(pAdapterInfo);
  371.     }
  372.     return S_OK;
  373. }
  374.  
  375.  
  376.  
  377.  
  378. //-----------------------------------------------------------------------------
  379. // Name: EnumerateDevices
  380. // Desc: Enumerates D3D devices for a particular adapter.
  381. //-----------------------------------------------------------------------------
  382. HRESULT CD3DEnumeration::EnumerateDevices( D3DAdapterInfo* pAdapterInfo, 
  383.                                            CArrayList* pAdapterFormatList )
  384. {
  385.     const D3DDEVTYPE devTypeArray[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_SW, D3DDEVTYPE_REF };
  386.     const UINT devTypeArrayCount = sizeof(devTypeArray) / sizeof(devTypeArray[0]);
  387.     HRESULT hr;
  388.  
  389.     D3DDeviceInfo* pDeviceInfo = NULL;
  390.     for( UINT idt = 0; idt < devTypeArrayCount; idt++ )
  391.     {
  392.         pDeviceInfo = new D3DDeviceInfo;
  393.         if( pDeviceInfo == NULL )
  394.             return E_OUTOFMEMORY;
  395.         pDeviceInfo->pDeviceComboList = new CArrayList( AL_REFERENCE ); 
  396.         if( pDeviceInfo->pDeviceComboList == NULL )
  397.         {
  398.             delete pDeviceInfo;
  399.             return E_OUTOFMEMORY;
  400.         }
  401.         pDeviceInfo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal;
  402.         pDeviceInfo->DevType = devTypeArray[idt];
  403.         if( FAILED( m_pD3D->GetDeviceCaps( pAdapterInfo->AdapterOrdinal, 
  404.             pDeviceInfo->DevType, &pDeviceInfo->Caps ) ) )
  405.         {
  406.             delete pDeviceInfo;
  407.             continue;
  408.         }
  409.  
  410.         // Get info for each devicecombo on this device
  411.         if( FAILED( hr = EnumerateDeviceCombos(pDeviceInfo, pAdapterFormatList) ) )
  412.         {
  413.             delete pDeviceInfo;
  414.             return hr;
  415.         }
  416.  
  417.         // If at least one devicecombo for this device is found, 
  418.         // add the deviceInfo to the list
  419.         if (pDeviceInfo->pDeviceComboList->Count() == 0)
  420.         {
  421.             delete pDeviceInfo;
  422.             continue;
  423.         }
  424.         pAdapterInfo->pDeviceInfoList->Add(pDeviceInfo);
  425.     }
  426.     return S_OK;
  427. }
  428.  
  429.  
  430.  
  431.  
  432. //-----------------------------------------------------------------------------
  433. // Name: EnumerateDeviceCombos
  434. // Desc: Enumerates DeviceCombos for a particular device.
  435. //-----------------------------------------------------------------------------
  436. HRESULT CD3DEnumeration::EnumerateDeviceCombos( D3DDeviceInfo* pDeviceInfo, 
  437.                                                CArrayList* pAdapterFormatList )
  438. {
  439.     const D3DFORMAT backBufferFormatArray[] = 
  440.         {   D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_A2R10G10B10, 
  441.             D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5 };
  442.     const UINT backBufferFormatArrayCount = sizeof(backBufferFormatArray) / sizeof(backBufferFormatArray[0]);
  443.     bool isWindowedArray[] = { false, true };
  444.  
  445.     // See which adapter formats are supported by this device
  446.     D3DFORMAT adapterFormat;
  447.     for( UINT iaf = 0; iaf < pAdapterFormatList->Count(); iaf++ )
  448.     {
  449.         adapterFormat = *(D3DFORMAT*)pAdapterFormatList->GetPtr(iaf);
  450.         D3DFORMAT backBufferFormat;
  451.         for( UINT ibbf = 0; ibbf < backBufferFormatArrayCount; ibbf++ )
  452.         {
  453.             backBufferFormat = backBufferFormatArray[ibbf];
  454.             if (AlphaChannelBits(backBufferFormat) < AppMinAlphaChannelBits)
  455.                 continue;
  456.             bool isWindowed;
  457.             for( UINT iiw = 0; iiw < 2; iiw++)
  458.             {
  459.                 isWindowed = isWindowedArray[iiw];
  460.                 if (!isWindowed && AppRequiresWindowed)
  461.                     continue;
  462.                 if (isWindowed && AppRequiresFullscreen)
  463.                     continue;
  464.                 if (FAILED(m_pD3D->CheckDeviceType(pDeviceInfo->AdapterOrdinal, pDeviceInfo->DevType, 
  465.                     adapterFormat, backBufferFormat, isWindowed)))
  466.                 {
  467.                     continue;
  468.                 }
  469.                 // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed
  470.                 // DeviceCombo that is supported by the system.  We still need to confirm that it's 
  471.                 // compatible with the app, and find one or more suitable depth/stencil buffer format,
  472.                 // multisample type, vertex processing type, and present interval.
  473.                 D3DDeviceCombo* pDeviceCombo = NULL;
  474.                 pDeviceCombo = new D3DDeviceCombo;
  475.                 if( pDeviceCombo == NULL )
  476.                     return E_OUTOFMEMORY;
  477.                 pDeviceCombo->pDepthStencilFormatList = new CArrayList( AL_VALUE, sizeof( D3DFORMAT ) );
  478.                 pDeviceCombo->pMultiSampleTypeList = new CArrayList( AL_VALUE, sizeof( D3DMULTISAMPLE_TYPE ) );
  479.                 pDeviceCombo->pMultiSampleQualityList = new CArrayList( AL_VALUE, sizeof( DWORD ) );
  480.                 pDeviceCombo->pDSMSConflictList = new CArrayList( AL_VALUE, sizeof( D3DDSMSConflict ) );
  481.                 pDeviceCombo->pVertexProcessingTypeList = new CArrayList( AL_VALUE, sizeof( VertexProcessingType ) );
  482.                 pDeviceCombo->pPresentIntervalList = new CArrayList( AL_VALUE, sizeof( UINT ) );
  483.                 if( pDeviceCombo->pDepthStencilFormatList == NULL ||
  484.                     pDeviceCombo->pMultiSampleTypeList == NULL || 
  485.                     pDeviceCombo->pMultiSampleQualityList == NULL || 
  486.                     pDeviceCombo->pDSMSConflictList == NULL || 
  487.                     pDeviceCombo->pVertexProcessingTypeList == NULL ||
  488.                     pDeviceCombo->pPresentIntervalList == NULL )
  489.                 {
  490.                     delete pDeviceCombo;
  491.                     return E_OUTOFMEMORY;
  492.                 }
  493.                 pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal;
  494.                 pDeviceCombo->DevType = pDeviceInfo->DevType;
  495.                 pDeviceCombo->AdapterFormat = adapterFormat;
  496.                 pDeviceCombo->BackBufferFormat = backBufferFormat;
  497.                 pDeviceCombo->IsWindowed = isWindowed;
  498.                 if (AppUsesDepthBuffer)
  499.                 {
  500.                     BuildDepthStencilFormatList(pDeviceCombo);
  501.                     if (pDeviceCombo->pDepthStencilFormatList->Count() == 0)
  502.                     {
  503.                         delete pDeviceCombo;
  504.                         continue;
  505.                     }
  506.                 }
  507.                 BuildMultiSampleTypeList(pDeviceCombo);
  508.                 if (pDeviceCombo->pMultiSampleTypeList->Count() == 0)
  509.                 {
  510.                     delete pDeviceCombo;
  511.                     continue;
  512.                 }
  513.                 BuildDSMSConflictList(pDeviceCombo);
  514.                 BuildVertexProcessingTypeList(pDeviceInfo, pDeviceCombo);
  515.                 if (pDeviceCombo->pVertexProcessingTypeList->Count() == 0)
  516.                 {
  517.                     delete pDeviceCombo;
  518.                     continue;
  519.                 }
  520.                 BuildPresentIntervalList(pDeviceInfo, pDeviceCombo);
  521.  
  522.                 pDeviceInfo->pDeviceComboList->Add(pDeviceCombo);
  523.             }
  524.         }
  525.     }
  526.  
  527.     return S_OK;
  528. }
  529.  
  530.  
  531.  
  532.  
  533. //-----------------------------------------------------------------------------
  534. // Name: BuildDepthStencilFormatList
  535. // Desc: Adds all depth/stencil formats that are compatible with the device 
  536. //       and app to the given D3DDeviceCombo.
  537. //-----------------------------------------------------------------------------
  538. void CD3DEnumeration::BuildDepthStencilFormatList( D3DDeviceCombo* pDeviceCombo )
  539. {
  540.     const D3DFORMAT depthStencilFormatArray[] = 
  541.     {
  542.         D3DFMT_D16,
  543.         D3DFMT_D15S1,
  544.         D3DFMT_D24X8,
  545.         D3DFMT_D24S8,
  546.         D3DFMT_D24X4S4,
  547.         D3DFMT_D32,
  548.     };
  549.     const UINT depthStencilFormatArrayCount = sizeof(depthStencilFormatArray) / 
  550.                                               sizeof(depthStencilFormatArray[0]);
  551.  
  552.     D3DFORMAT depthStencilFmt;
  553.     for( UINT idsf = 0; idsf < depthStencilFormatArrayCount; idsf++ )
  554.     {
  555.         depthStencilFmt = depthStencilFormatArray[idsf];
  556.         if (DepthBits(depthStencilFmt) < AppMinDepthBits)
  557.             continue;
  558.         if (StencilBits(depthStencilFmt) < AppMinStencilBits)
  559.             continue;
  560.         if (SUCCEEDED(m_pD3D->CheckDeviceFormat(pDeviceCombo->AdapterOrdinal, 
  561.             pDeviceCombo->DevType, pDeviceCombo->AdapterFormat, 
  562.             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFmt)))
  563.         {
  564.             if (SUCCEEDED(m_pD3D->CheckDepthStencilMatch(pDeviceCombo->AdapterOrdinal, 
  565.                 pDeviceCombo->DevType, pDeviceCombo->AdapterFormat, 
  566.                 pDeviceCombo->BackBufferFormat, depthStencilFmt)))
  567.             {
  568.                 pDeviceCombo->pDepthStencilFormatList->Add(&depthStencilFmt);
  569.             }
  570.         }
  571.     }
  572. }
  573.  
  574.  
  575.  
  576.  
  577. //-----------------------------------------------------------------------------
  578. // Name: BuildMultiSampleTypeList
  579. // Desc: Adds all multisample types that are compatible with the device and app to
  580. //       the given D3DDeviceCombo.
  581. //-----------------------------------------------------------------------------
  582. void CD3DEnumeration::BuildMultiSampleTypeList( D3DDeviceCombo* pDeviceCombo )
  583. {
  584.     const D3DMULTISAMPLE_TYPE msTypeArray[] = { 
  585.         D3DMULTISAMPLE_NONE,
  586.         D3DMULTISAMPLE_NONMASKABLE,
  587.         D3DMULTISAMPLE_2_SAMPLES,
  588.         D3DMULTISAMPLE_3_SAMPLES,
  589.         D3DMULTISAMPLE_4_SAMPLES,
  590.         D3DMULTISAMPLE_5_SAMPLES,
  591.         D3DMULTISAMPLE_6_SAMPLES,
  592.         D3DMULTISAMPLE_7_SAMPLES,
  593.         D3DMULTISAMPLE_8_SAMPLES,
  594.         D3DMULTISAMPLE_9_SAMPLES,
  595.         D3DMULTISAMPLE_10_SAMPLES,
  596.         D3DMULTISAMPLE_11_SAMPLES,
  597.         D3DMULTISAMPLE_12_SAMPLES,
  598.         D3DMULTISAMPLE_13_SAMPLES,
  599.         D3DMULTISAMPLE_14_SAMPLES,
  600.         D3DMULTISAMPLE_15_SAMPLES,
  601.         D3DMULTISAMPLE_16_SAMPLES,
  602.     };
  603.     const UINT msTypeArrayCount = sizeof(msTypeArray) / sizeof(msTypeArray[0]);
  604.  
  605.     D3DMULTISAMPLE_TYPE msType;
  606.     DWORD msQuality;
  607.     for( UINT imst = 0; imst < msTypeArrayCount; imst++ )
  608.     {
  609.         msType = msTypeArray[imst];
  610.         if (SUCCEEDED(m_pD3D->CheckDeviceMultiSampleType(pDeviceCombo->AdapterOrdinal, pDeviceCombo->DevType, 
  611.             pDeviceCombo->BackBufferFormat, pDeviceCombo->IsWindowed, msType, &msQuality)))
  612.         {
  613.             pDeviceCombo->pMultiSampleTypeList->Add(&msType);
  614.             pDeviceCombo->pMultiSampleQualityList->Add( &msQuality );
  615.         }
  616.     }
  617. }
  618.  
  619.  
  620.  
  621.  
  622. //-----------------------------------------------------------------------------
  623. // Name: BuildDSMSConflictList
  624. // Desc: Find any conflicts between the available depth/stencil formats and
  625. //       multisample types.
  626. //-----------------------------------------------------------------------------
  627. void CD3DEnumeration::BuildDSMSConflictList( D3DDeviceCombo* pDeviceCombo )
  628. {
  629.     D3DDSMSConflict DSMSConflict;
  630.  
  631.     for( UINT ids = 0; ids < pDeviceCombo->pDepthStencilFormatList->Count(); ids++ )
  632.     {
  633.         D3DFORMAT dsFmt = *(D3DFORMAT*)pDeviceCombo->pDepthStencilFormatList->GetPtr(ids);
  634.         for( UINT ims = 0; ims < pDeviceCombo->pMultiSampleTypeList->Count(); ims++ )
  635.         {
  636.             D3DMULTISAMPLE_TYPE msType = *(D3DMULTISAMPLE_TYPE*)pDeviceCombo->pMultiSampleTypeList->GetPtr(ims);
  637.             if( FAILED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, pDeviceCombo->DevType,
  638.                 dsFmt, pDeviceCombo->IsWindowed, msType, NULL ) ) )
  639.             {
  640.                 DSMSConflict.DSFormat = dsFmt;
  641.                 DSMSConflict.MSType = msType;
  642.                 pDeviceCombo->pDSMSConflictList->Add( &DSMSConflict );
  643.             }
  644.         }
  645.     }
  646. }
  647.  
  648.  
  649.  
  650.  
  651. //-----------------------------------------------------------------------------
  652. // Name: BuildVertexProcessingTypeList
  653. // Desc: Adds all vertex processing types that are compatible with the device 
  654. //       and app to the given D3DDeviceCombo.
  655. //-----------------------------------------------------------------------------
  656. void CD3DEnumeration::BuildVertexProcessingTypeList( D3DDeviceInfo* pDeviceInfo, 
  657.                                                      D3DDeviceCombo* pDeviceCombo )
  658. {
  659.     VertexProcessingType vpt;
  660.     if ((pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
  661.     {
  662.         if ((pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0)
  663.         {
  664.             if (ConfirmDeviceCallback == NULL ||
  665.                 ConfirmDeviceCallback(&pDeviceInfo->Caps, PURE_HARDWARE_VP, pDeviceCombo->BackBufferFormat))
  666.             {
  667.                 vpt = PURE_HARDWARE_VP;
  668.                 pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
  669.             }
  670.         }
  671.         if (ConfirmDeviceCallback == NULL ||
  672.             ConfirmDeviceCallback(&pDeviceInfo->Caps, HARDWARE_VP, pDeviceCombo->BackBufferFormat))
  673.         {
  674.             vpt = HARDWARE_VP;
  675.             pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
  676.         }
  677.         if (AppUsesMixedVP && (ConfirmDeviceCallback == NULL ||
  678.             ConfirmDeviceCallback(&pDeviceInfo->Caps, MIXED_VP, pDeviceCombo->BackBufferFormat)))
  679.         {
  680.             vpt = MIXED_VP;
  681.             pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
  682.         }
  683.     }
  684.     if (ConfirmDeviceCallback == NULL ||
  685.         ConfirmDeviceCallback(&pDeviceInfo->Caps, SOFTWARE_VP, pDeviceCombo->BackBufferFormat))
  686.     {
  687.         vpt = SOFTWARE_VP;
  688.         pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
  689.     }
  690. }
  691.  
  692.  
  693.  
  694.  
  695. //-----------------------------------------------------------------------------
  696. // Name: BuildPresentIntervalList
  697. // Desc: Adds all present intervals that are compatible with the device and app 
  698. //       to the given D3DDeviceCombo.
  699. //-----------------------------------------------------------------------------
  700. void CD3DEnumeration::BuildPresentIntervalList( D3DDeviceInfo* pDeviceInfo, 
  701.                                                 D3DDeviceCombo* pDeviceCombo )
  702. {
  703.     const UINT piArray[] = { 
  704.         D3DPRESENT_INTERVAL_IMMEDIATE,
  705.         D3DPRESENT_INTERVAL_DEFAULT,
  706.         D3DPRESENT_INTERVAL_ONE,
  707.         D3DPRESENT_INTERVAL_TWO,
  708.         D3DPRESENT_INTERVAL_THREE,
  709.         D3DPRESENT_INTERVAL_FOUR,
  710.     };
  711.     const UINT piArrayCount = sizeof(piArray) / sizeof(piArray[0]);
  712.  
  713.     UINT pi;
  714.     for( UINT ipi = 0; ipi < piArrayCount; ipi++ )
  715.     {
  716.         pi = piArray[ipi];
  717.         if( pDeviceCombo->IsWindowed )
  718.         {
  719.             if( pi == D3DPRESENT_INTERVAL_TWO ||
  720.                 pi == D3DPRESENT_INTERVAL_THREE ||
  721.                 pi == D3DPRESENT_INTERVAL_FOUR )
  722.             {
  723.                 // These intervals are not supported in windowed mode.
  724.                 continue;
  725.             }
  726.         }
  727.         // Note that D3DPRESENT_INTERVAL_DEFAULT is zero, so you
  728.         // can't do a caps check for it -- it is always available.
  729.         if( pi == D3DPRESENT_INTERVAL_DEFAULT ||
  730.             (pDeviceInfo->Caps.PresentationIntervals & pi) )
  731.         {
  732.             pDeviceCombo->pPresentIntervalList->Add( &pi );
  733.         }
  734.     }
  735. }
  736.